#include "Utils.hpp"

#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctime>

#ifdef LINUX
#include <termios.h>
#include <sys/time.h>
#include <unistd.h>
#endif


#ifdef LINUX
int getch(void)
{
    int c = 0;
    int res = -1;
    struct termios org_opts, new_opts;

    res = tcgetattr(STDIN_FILENO, &org_opts);
    assert(res == 0);
    memcpy(&new_opts, &org_opts, sizeof(org_opts));
    new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE);
    tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);

    c = getchar();

    res = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
    assert(res == 0);

    return c;
}
#endif

// return a random number within [start, end] or [end, start]
int RandomGenerator(int start, int end) {
  static bool firstCall = false;
  if (start == end) return start;

  if (!firstCall) {
    srand((unsigned int)time(0));
    firstCall = true;
  }
  int larger = start > end ? start : end;
  int smaller = start > end ? end : start;
  int offset = smaller;
  int length = larger - smaller;

  int randomNum = rand() % (length+1);
  return randomNum + offset;
}

#ifndef LINUX
int gettimeofday(struct timeval *tp, void *tzp)
{
    time_t clock;
    struct tm tm;
    SYSTEMTIME wtm;

    GetLocalTime(&wtm);
    tm.tm_year     = wtm.wYear - 1900;
    tm.tm_mon     = wtm.wMonth - 1;
    tm.tm_mday     = wtm.wDay;
    tm.tm_hour     = wtm.wHour;
    tm.tm_min     = wtm.wMinute;
    tm.tm_sec     = wtm.wSecond;
    tm. tm_isdst    = -1;
    clock = mktime(&tm);
    tp->tv_sec = clock;
    tp->tv_usec = wtm.wMilliseconds * 1000;

    return (0);
}
#endif
